home *** CD-ROM | disk | FTP | other *** search
/ 1,000 Games / 1000 Games.toast / Chess Games / GNU Chess 3.0 / Gnu Chess Source / mac.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-15  |  30.7 KB  |  1,501 lines  |  [TEXT/KAHL]

  1. /*
  2.   Mac interface for GNU Chess
  3.  
  4.   Revision: 10 Feb 1991
  5.  
  6.   Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
  7.   Copyright (c) 1991  Airy ANDRE
  8.  
  9.     expanded game save, list, and restore features
  10.     optional auto-updating of positional information
  11.  
  12.   This file is part of CHESS.
  13.  
  14.   CHESS is distributed in the hope that it will be useful,
  15.   but WITHOUT ANY WARRANTY.  No author or distributor
  16.   accepts responsibility to anyone for the consequences of using it
  17.   or for whether it serves any particular purpose or works at all,
  18.   unless he says so in writing.  Refer to the CHESS General Public
  19.   License for full details.
  20.  
  21.   Everyone is granted permission to copy, modify and redistribute
  22.   CHESS, but only under the conditions described in the
  23.   CHESS General Public License.   A copy of this license is
  24.   supposed to have been given to you along with CHESS so you
  25.   can know your rights and responsibilities.  It should be in a
  26.   file named COPYING.  Among other things, the copyright notice
  27.   and this notice must be preserved on all copies.
  28.   */
  29.  
  30. #include <stdio.h>
  31. #include "math.h"
  32.  
  33. #include "DragMgr.h"
  34. #include "gnuchess.h"
  35. #include "macintf.h"
  36. #include "rsrc.h"
  37.  
  38.  
  39. char mvstr[5][6];
  40. long evrate;
  41.  
  42. short PositionFlag = 0;
  43. short coords = 1;
  44. short stars = 0;
  45. short rv = 1;
  46. short shade = 0;
  47. short preview = 0;
  48. short idoit = 0;
  49. short drawn = 0;
  50. short undo = 0;
  51. short anim = 1;
  52. short showvalue = 0;
  53. short newgame = 0;
  54. short getgame = 0;
  55. short wne;
  56.  
  57. char buff[100];
  58.  
  59. Boolean    Finished;
  60. CursHandle    ClockCursor;
  61. CursHandle    ArrowCursor;
  62. CursHandle    CrossCursor;
  63. Rect    DragArea;
  64. Rect    GrowArea;
  65. MenuHandle    Menu;
  66. WindowPtr    WindBoard, WindList, WindThink;
  67. int    width,height;
  68.  
  69. short background = 0;
  70.  
  71. Point    thePoint;
  72. Rect    MinSize;
  73.     
  74. Rect    nameRec, ValueRec, ValueFRec,chessRectOff;
  75.  
  76. Rect    MsgRec, MsgFRec;
  77. Rect    ThinkRec[2], ThinkFRec[2];
  78. Rect     ScoreRec, ScoreFRec;
  79.  
  80. int     theScore;
  81. Str255    Msg;
  82.  
  83. Str255    ThinkMove[2][30];
  84. int        maxThink;
  85.  
  86. DragHandle    myDragStuff;
  87. Point    pt;
  88.  
  89. Pattern blackPat, whitePat;
  90.  
  91. Rect    CaseRec, CaseFRec;
  92. int        MouseX, MouseY;
  93.  
  94. int     ref;
  95. long    nbre;
  96.  
  97. short saveBoard[64], saveColor[64];
  98.  
  99. int towho;
  100.  
  101. ListHandle List;
  102. Rect theBar;
  103.  
  104.  
  105. void SetUpThing(void)
  106. {    
  107.     int typ,err,i,j;
  108.     Handle Hitem;
  109.     Rect r;
  110.  
  111.     FlushEvents(everyEvent,0);
  112.  
  113.     MoreMasters();
  114.     MoreMasters();
  115.     MoreMasters();
  116.     MoreMasters();
  117.     MoreMasters();
  118.     MaxApplZone();
  119.  
  120.     InitGraf(&thePort);
  121.     InitFonts();
  122.     InitWindows();
  123.     InitMenus();
  124.     TEInit();
  125.     InitDialogs(0L);
  126.  
  127.     ClockCursor=GetCursor(watchCursor);
  128.     ArrowCursor=GetCursor(1000);
  129.     HNoPurge((Handle)ClockCursor);
  130.     HNoPurge((Handle)ArrowCursor);
  131.     SetCursor(*ClockCursor);
  132.     
  133.     StuffHex(blackPat, "\pFFFFFFFFFFFFFFFF");
  134.     StuffHex(whitePat, "\p0000000000000000");
  135.  
  136. #define WNETrapNum 0x60
  137. #define UnImplTrapNum 0x9F
  138.  
  139.     wne = NGetTrapAddress(WNETrapNum, ToolTrap) ==
  140.                     NGetTrapAddress(UnImplTrapNum, ToolTrap);
  141. }
  142.  
  143. void SetupMenus(void)
  144. {
  145.     MenuHandle MenuTopic ;
  146.     int index;
  147.  
  148.     MenuTopic=GetMenu(AppleMenu);
  149.     AddResMenu(MenuTopic,'DRVR');
  150.     InsertMenu(MenuTopic,0);
  151.  
  152.     for (index=FileMenu; index<=OptionsMenu; index++)
  153.             InsertMenu(GetMenu(index),0);
  154.  
  155.     InsertMenu(GetMenu(BlackMenu),-1);
  156.     InsertMenu(GetMenu(WhiteMenu),-1);
  157.  
  158.     DrawMenuBar();
  159. }
  160.  
  161.  
  162. void
  163. ShowPMessage (char *s)
  164. {
  165.   BlockMove(s, Msg, (long)*s + 1);
  166.   UpdateMsg(NULL, 3);
  167. }
  168.  
  169. void
  170. ShowCMessage (char *s)
  171. {
  172.   *Msg = strlen(s);
  173.   strcpy(Msg+1, s);
  174.   UpdateMsg(NULL, 3);
  175. }
  176.  
  177.  
  178. int RemoveMove(int GameCnt)
  179. {
  180.   Cell theCell;
  181.  
  182.   theCell.v = GameCnt/2;
  183.  
  184.   if (!(GameCnt&1)) {
  185.       LDelRow(1, theCell.v, List);
  186.   } else {
  187.       theCell.h = 1;
  188.       LClrCell(theCell, List);
  189.   }
  190.   
  191.   LScroll(0, 10000, List);
  192. }
  193.  
  194. int ShowError(int errno)
  195. {
  196.     ParamText(*GetString(errno), "", "", "");
  197.     return CautionAlert(_ERROR_ALRT, NULL);
  198. }
  199.  
  200. int AreYouSure(num)
  201. {
  202.     ParamText(*GetString(num), "", "", "");
  203.     return CautionAlert(_CONFIRM_ALRT, NULL) == 2;
  204. }
  205.  
  206. char choosePromo()
  207. {
  208.     int item;
  209.     DialogPtr theDlog;
  210.     
  211.     theDlog = GetNewDialog(_PROMO_DLOG,(DialogPeek)0L,(WindowPtr)-1L);
  212.     
  213.     SetPort(theDlog);
  214.     
  215.     ModalDialog(NULL, &item);
  216.     
  217.     DisposDialog(theDlog);
  218.     
  219.     switch (item) {
  220.         case 1: return 'Q';
  221.         case 2: return 'N';
  222.         case 3: return 'R';
  223.         case 4: return 'B';
  224.     }
  225. }
  226.  
  227. int chooseTime(int *moves, int *minutes)
  228. {
  229.     int item;
  230.     DialogPtr theDlog;
  231.     Str255 str;
  232.     long res;
  233.     Handle hdl;
  234.     Rect theRect;
  235.     int type;
  236.     
  237.     theDlog = GetNewDialog(_TIME_DLOG,(DialogPeek)0L,(WindowPtr)-1L);
  238.     
  239.     GetDItem(theDlog, 6, &type, &hdl, &theRect);
  240.     NumToString(*moves, str);
  241.     SetIText(hdl, str);
  242.     GetDItem(theDlog, 5, &type, &hdl, &theRect);
  243.     NumToString(*minutes, str);
  244.     SetIText(hdl, str);
  245.     
  246.     SetPort(theDlog);
  247.     
  248.     
  249.     do {
  250.         ModalDialog(NULL, &item);
  251.     } while ((item != 1) && (item != 2));
  252.     
  253.     if (item == 1) {
  254.         GetDItem(theDlog, 6, &type, &hdl, &theRect);
  255.         GetIText(hdl, str);
  256.         StringToNum(str, &res);
  257.         *moves = res;
  258.         GetDItem(theDlog, 5, &type, &hdl, &theRect);
  259.         GetIText(hdl, str);
  260.         StringToNum(str, &res);
  261.         *minutes = res;
  262.     }
  263.     
  264.     DisposDialog(theDlog);
  265.     
  266.     return (item==1);
  267. }
  268.  
  269. int AddMove(int GameCnt, char *mvstr)
  270. {
  271.   Cell theCell;
  272.   char mv[10];
  273.  
  274.   theCell.v = GameCnt/2;
  275.  
  276.   if (!(GameCnt&1)) {
  277.     int num = theCell.v + 1;
  278.     
  279.       theCell.h = 0;
  280.       LAddRow(1, theCell.v, List);
  281.       mv[0] = (num / 100)?(num/100 + '0'):' ';
  282.       mv[1] = ((num % 100) / 10)?((num % 100)/10 + '0'):' ';
  283.       mv[2] = num%10 + '0';
  284.       mv[3] = '.';
  285.       strcpy(mv + 4, mvstr);
  286.   } else {
  287.       theCell.h = 1;
  288.       strcpy(mv, mvstr);
  289.   }
  290.   
  291.   LSetCell((Ptr)mv, strlen(mv), theCell, List);
  292.   LDraw(theCell, List);
  293.   LScroll(0, 10000, List);
  294. }
  295.  
  296.  
  297. void
  298. Initialize ()
  299. {
  300.  int    i,j;
  301.  Rect    r;
  302.  Handle Hitem;
  303.  Cell Csize;
  304.  Rect bound;
  305.  
  306.     SetRect(&DragArea,
  307.             screenBits.bounds.left+4,
  308.             screenBits.bounds.top+24,
  309.             screenBits.bounds.right-4,
  310.             screenBits.bounds.bottom-4);
  311.     SetRect(&GrowArea,
  312.             80,
  313.             screenBits.bounds.top+60,
  314.             screenBits.bounds.right,
  315.             screenBits.bounds.bottom);
  316.     
  317.     WindBoard = GetNewDialog(770,(DialogPeek)0L,(WindowPtr)-1L);    
  318.     SetPort(WindBoard);
  319.     TextFont(geneva);
  320.     TextSize(9);
  321.     GetDItem(WindBoard, 1, &i, &Hitem, &chessRectOff);
  322.     SetDItem(WindBoard, 1, i, (Handle)UpdateGraphic, &chessRectOff);
  323.     width = 1+(chessRectOff.right-chessRectOff.left)/8;
  324.     height = width;
  325.  
  326.     GetDItem(WindBoard, 2, &i, &Hitem, &CaseFRec);
  327.     SetDItem(WindBoard, 2, i, (Handle)UpdateCase, &CaseFRec);
  328.     CaseRec = CaseFRec;
  329.     InsetRect(&CaseRec, 1, 1);
  330.         
  331.     
  332.     WindThink = GetNewDialog(_THINK_DLOG,(DialogPeek)0L,(WindowPtr)-1L);
  333.     SetPort(WindThink);
  334.     TextFont(monaco);
  335.     TextSize(9);
  336.     
  337.     GetDItem(WindThink, 1, &i, &Hitem, &nameRec);
  338.     SetDItem(WindThink, 1, i,  (Handle)UpdateChronos, &nameRec);
  339.     
  340.     GetDItem(WindThink, 5, &i, &Hitem, &ValueFRec);
  341.     SetDItem(WindThink, 5, i, (Handle)UpdateValue, &ValueFRec);
  342.     ValueRec = ValueFRec;
  343.     InsetRect(&ValueRec, 1, 1);
  344.     
  345.     GetDItem(WindThink, 4, &i, &Hitem, &MsgFRec);
  346.     SetDItem(WindThink, 4, i, (Handle)UpdateMsg, &MsgFRec);
  347.     MsgRec = MsgFRec;
  348.     InsetRect(&MsgRec, 1, 1);
  349.             
  350.     GetDItem(WindThink, 2, &i, &Hitem, &ThinkFRec[0]);
  351.     SetDItem(WindThink, 2, i, (Handle)UpdateThink, &ThinkFRec[0]);
  352.     ThinkRec[0] = ThinkFRec[0];
  353.     InsetRect(&ThinkRec[0], 1, 1);
  354.             
  355.     GetDItem(WindThink, 3, &i, &Hitem, &ThinkFRec[1]);
  356.     SetDItem(WindThink, 3, i, (Handle)UpdateThink, &ThinkFRec[1]);
  357.     ThinkRec[1] = ThinkFRec[1];
  358.     InsetRect(&ThinkRec[1], 1, 1);
  359.     
  360.     maxThink = (ThinkRec[1].bottom - ThinkRec[1].top - 5)/12 - 1;
  361.     
  362.     WindList = GetNewDialog(768, (DialogPeek)0L, (WindowPtr)-1L);
  363.     SetPort(WindList);
  364.     TextSize(9);
  365.     TextFont(monaco);
  366.     GetDItem(WindList, 1, &i, &Hitem, &r);
  367.     SetDItem(WindList, 1, i, (Handle)UpdateListe, &r);
  368.     r.right -= 15;
  369.     Csize.v=12;Csize.h=(r.right-r.left)/2;
  370.     bound.top = 0;
  371.     bound.left = 0;
  372.     bound.right = 2;
  373.     bound.bottom = 0;
  374.     List=LNew(&r,&bound,Csize,0,WindList,TRUE,FALSE,FALSE,TRUE);
  375.  
  376.     theBar = r;
  377.     theBar.left = r.right;
  378.     theBar.right += 15;
  379.     
  380.        (**List).selFlags=lOnlyOne;
  381.                     
  382.     LAutoScroll(List);
  383.  
  384.     ShowWindow(WindList);
  385.     
  386.     SetPort(WindBoard);
  387.     MouseX = MouseY = 0;
  388.         
  389.     UpdateChronos(NULL, 2);
  390.     UpdateValue(NULL, 5);
  391.     UpdateMsg(NULL, 3);
  392.     UpdateCase(NULL, 4);
  393.     
  394.     SetPort(WindBoard);
  395.     InitDrag(0L, &chessRectOff);
  396.     UpdateDisplay(0,0,1,0,1,color,board);
  397.     
  398.     InitCursor();
  399. }
  400.  
  401. void
  402. ExitChess ()
  403. {
  404.   CloseDrag(0);
  405. }
  406.  
  407.  
  408. void
  409. algbr (f, t, flag)
  410.      short int f;
  411.      short int t;
  412.      short int flag;
  413. /*
  414.    Generate move strings in different formats, a hook has been provided for
  415.    underpromotion
  416. */
  417.  
  418. {
  419.   int m3p;
  420.  
  421.   if (f != t)
  422.     {
  423.       /* algebraic notation */
  424.       mvstr[0][0] = cxx[column (f)];
  425.       mvstr[0][1] = rxx[row (f)];
  426.       mvstr[0][2] = cxx[column (t)];
  427.       mvstr[0][3] = rxx[row (t)];
  428.       mvstr[0][4] = '\0';
  429.       mvstr[3][0] = '\0';
  430.       if ((mvstr[1][0] = qxx[board[f]]) == 'P')
  431.     {
  432.       if (mvstr[0][0] == mvstr[0][2])    /* pawn did not eat */
  433.         {
  434.           mvstr[2][0] = mvstr[1][0] = mvstr[0][2];    /* to column */
  435.           mvstr[2][1] = mvstr[1][1] = mvstr[0][3];    /* to row */
  436.           m3p = 2;
  437.         }
  438.       else
  439.         /* pawn ate */
  440.         {
  441.           mvstr[2][0] = mvstr[1][0] = mvstr[0][0];    /* from column */
  442.           mvstr[2][1] = mvstr[1][1] = mvstr[0][2];    /* to column */
  443.           mvstr[2][2] = mvstr[0][3];
  444.           m3p = 3;        /* to row */
  445.         }
  446.       mvstr[2][m3p] = mvstr[1][2] = '\0';
  447.       if (flag & promote)
  448.         {
  449.           mvstr[0][4] = mvstr[1][2] = mvstr[2][m3p] = qxx[flag & pmask];
  450.           mvstr[1][3] = mvstr[2][m3p + 1] = mvstr[0][5] = '\0';
  451.         }
  452.     }
  453.       else
  454.     /* not a pawn */
  455.     {
  456.       mvstr[2][0] = mvstr[1][0];
  457.       mvstr[2][2] = mvstr[1][1] = mvstr[0][2];    /* to column */
  458.       mvstr[2][3] = mvstr[1][2] = mvstr[0][3];    /* to row */
  459.       mvstr[2][4] = mvstr[1][3] = '\0';
  460.       mvstr[2][1] = mvstr[0][1];
  461.       strcpy (mvstr[3], mvstr[2]);
  462.       mvstr[3][1] = mvstr[0][0];
  463.       if (flag & cstlmask)
  464.         {
  465.           if (t > f)
  466.         {
  467.           strcpy (mvstr[1], "o-o");
  468.           strcpy (mvstr[2], "O-O");
  469.         }
  470.           else
  471.         {
  472.           strcpy (mvstr[1], "o-o-o");
  473.           strcpy (mvstr[2], "O-O-O");
  474.         }
  475.         }
  476.     }
  477.     }
  478.   else
  479.     mvstr[0][0] = mvstr[1][0] = mvstr[2][0] = mvstr[3][0] = '\0';
  480. }
  481.  
  482. void
  483. seteasy()
  484. {
  485.   easy = !easy;
  486. }
  487.  
  488.  
  489. int
  490. VerifyMove (s, iop, mv)
  491.      char *s;
  492.      short int iop;
  493.      short unsigned int *mv;
  494. /*
  495.    Compare the string 's' to the list of legal moves available for the
  496.    opponent. If a match is found, make the move on the board.
  497. */
  498. {
  499.   static short pnt, tempb, tempc, tempsf, tempst, cnt;
  500.   static struct leaf xnode;
  501.   struct leaf *node;
  502.  
  503.   *mv = 0;
  504.   if (iop == 2)
  505.     {
  506.       UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  507.       return (false);
  508.     }
  509.   cnt = 0;
  510.   MoveList (opponent, 2);
  511.   pnt = TrPnt[2];
  512.   while (pnt < TrPnt[3])
  513.     {
  514.       node = &Tree[pnt++];
  515.       algbr (node->f, node->t, (short) node->flags);
  516.       if (strcmp (s, mvstr[0]) == 0 || strcmp (s, mvstr[1]) == 0 ||
  517.           strcmp (s, mvstr[2]) == 0 || strcmp (s, mvstr[3]) == 0)
  518.         {
  519.           cnt++;
  520.           xnode = *node;
  521.         }
  522.     }
  523.   if (cnt == 1)
  524.     {
  525.       MakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst, 0);
  526.       if (SqAtakd (PieceList[opponent][0], computer))
  527.         {
  528.           UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  529.           return (false);
  530.         }
  531.       else
  532.         {
  533.           if (iop == 1)
  534.             return (true);
  535.           if (xnode.flags & cstlmask)
  536.             Game50 = GameCnt;
  537.           else if (board[xnode.t] == pawn || (xnode.flags & capture))
  538.             Game50 = GameCnt;
  539.           GameList[GameCnt].depth = GameList[GameCnt].score = 0;
  540.           GameList[GameCnt].nodes = 0;
  541.           GameList[GameCnt].time = (short) et;
  542.           GameList[GameCnt].flags = xnode.flags;
  543.           TimeControl.clock[opponent] -= et;
  544.           --TimeControl.moves[opponent];
  545.           
  546.           ElapsedTime(1);
  547.  
  548.           *mv = (xnode.f << 8) + xnode.t;
  549.           algbr (xnode.f, xnode.t, xnode.flags);
  550.  
  551.           if (xnode.flags & epmask)
  552.             UpdateDisplay (0, 0, 1, 0, 1, color, board);
  553.           else
  554.             UpdateDisplay(xnode.f, xnode.t, 0, (short) xnode.flags & cstlmask, 0,
  555.                            color, board);
  556.           return (true);
  557.         }
  558.     }
  559.   return (false);
  560. }
  561.  
  562. void
  563. ShowResults (score, bstline, ch)
  564.      short int score;
  565.      short unsigned int *bstline;
  566.      char ch;
  567. {
  568.   short d, e, ply;
  569.   theScore = score;
  570.   if (showvalue) UpdateValue(0L,5);
  571.   if (post)
  572.     {
  573.       GrafPtr SavePort;
  574.       int h,v;
  575.       
  576.        GetPort(&SavePort);
  577.       SetPort(WindThink);
  578.       TextMode(srcCopy);
  579.  
  580.       d = 0;
  581.       
  582.       h = ThinkRec[computer].left+2;
  583.       v = ThinkRec[computer].top+15;
  584.       
  585.       for (ply = 1; bstline[ply] > 0; ply++)
  586.     {
  587.       algbr (bstline[ply] >> 8, bstline[ply] & 0xFF, false);
  588.       strcpy(ThinkMove[computer][d]+1, mvstr[0]);
  589.       ThinkMove[computer][d][0] = strlen(mvstr[0]);
  590.       MoveTo(h,v);
  591.       DrawString(ThinkMove[computer][d]);
  592.       if (++d>maxThink) break;
  593.       v += 12;
  594.     }
  595.       lpost = d;
  596.       while (d <= maxThink)
  597.     {
  598.       MoveTo(h,v);
  599.       ThinkMove[computer][d++][0] = 0;
  600.       v += 12;
  601.       DrawString("\p       ");
  602.     }
  603.     SetPort(SavePort);
  604.     }
  605. }
  606.  
  607.  
  608. void
  609. SearchStartStuff (side)
  610.      short int side;
  611. {
  612.   short i;
  613.   
  614.   SetPort(WindThink);
  615.   ThinkMove[side][0][0] = 0;
  616.   EraseRect(&ThinkRec[side]);
  617. }
  618.  
  619. void
  620. OutputMove ()
  621. {
  622.   int i;
  623.  
  624.   ShowCMessage(""); 
  625.   if (SqAtakd (PieceList[!towho][0], towho))
  626.   {
  627.     ShowPMessage(*(char **)GetString(_CHECK_STR));
  628.   }
  629.   
  630.   AddMove(GameCnt, mvstr[(root->flags & cstlmask) != 0]);
  631.   
  632.   for (i=0; i<64; i++) {
  633.       saveBoard[i] = board[i];
  634.       saveColor[i] = color[i];
  635.   }
  636.   
  637.   if (root->flags & epmask)
  638.     UpdateDisplay (0, 0, 1, 0, 1, color, board);
  639.   else
  640.     UpdateDisplay (root->f, root->t, 0, root->flags & cstlmask, 1, color, board);
  641.  
  642.   if (root->flags & draw) {
  643.     ShowPMessage(*(char **)GetString(_DRAWN_STR));
  644.     drawn = true;
  645.   }
  646.   else if (root->score == -9999) {
  647.     ShowPMessage(*(char **)GetString(_MATE_STR));
  648.   }
  649.   else if (root->score == 9998) {
  650.     ShowPMessage(*(char **)GetString(_MATE_STR));
  651.   }
  652.   else if (root->score < -9000) {
  653.     ShowPMessage(*(char **)GetString(_SOON_STR));
  654.   }
  655.   else if (root->score > 9000) {
  656.     ShowPMessage(*(char **)GetString(_SOON_STR));
  657.   }
  658. }
  659.  
  660. void
  661. ElapsedTime(iop)
  662.      short int iop;
  663. /*
  664.   Determine the time that has passed since the search was started. If
  665.   the elapsed time exceeds the target (ResponseTime+ExtraTime) then set
  666.   timeout to true which will terminate the search.
  667. */
  668. {
  669.   static unsigned long LastClick = 0;
  670.   
  671.   et = (Ticks - time0)/60;
  672.   if (et < 0) {
  673.       et = 0;
  674.   }
  675.   if (((Ticks-LastClick)>10) && (towho == computer || bothsides || preview)) {
  676.       if (mainLoop()) timeout = true;
  677.       LastClick = Ticks;
  678.   }
  679.  
  680.   ETnodes += 50;
  681.   if (et > et0 || iop == 1)
  682.     {
  683.       if (et > ResponseTime + ExtraTime && Sdepth > 1)
  684.             timeout = true;
  685.       et0 = et;
  686.       if (iop == 1)
  687.       {
  688.             time0 = Ticks;
  689.             et0 = 0;
  690.       }
  691.       if (et > 0)
  692.             /* evrate is Nodes / cputime */
  693.             evrate = NodeCnt / (et + ft);
  694.       else    evrate = 0;
  695.       
  696.       ETnodes = NodeCnt + 50;
  697.       UpdateClocks ();
  698.     }
  699.     
  700. }
  701.  
  702. void
  703. UpdateClocks ()
  704. {    
  705.     static unsigned long LastDraw = 0;
  706.     static int LastColor = black;
  707.     
  708.     if (LastColor!=towho || Ticks-LastDraw>45) {
  709.             UpdateChronos(NULL, 0);
  710.             LastDraw = Ticks; LastColor = towho;
  711.     }
  712. }
  713.  
  714.  
  715. void
  716. SetTimeControl (color)
  717. {
  718.   if (TCflag[color])
  719.     {
  720.       TimeControl.moves[color] = TCmoves[color];
  721.       TimeControl.clock[color] = 60 * (long) TCminutes[color];
  722.     }
  723.   else
  724.     {
  725.       TimeControl.moves[color] = 0;
  726.       TimeControl.clock[color] = 0;
  727.       Level[color] = 60 * (long) TCminutes[color];
  728.     }
  729.   et = 0;
  730.   ElapsedTime (1);
  731. }
  732.  
  733.  
  734. void
  735. Undo ()
  736. /*
  737.   Undo the most recent half-move.
  738.   */
  739. {
  740.   short f, t, i;
  741.   
  742.   RemoveMove(GameCnt);
  743.   f = GameList[GameCnt].gmove >> 8;
  744.   t = GameList[GameCnt].gmove & 0xFF;
  745.   if (board[t] == king && distance (t, f) > 1)
  746.     {
  747.         castle (GameList[GameCnt].color, f, t, 2);
  748.           DrawPieces (PieceToNum(color[t], board[t]), t);
  749.           DrawPieces (PieceToNum(color[f], board[f]), f);    
  750.           if (distance(t,f) == 2) {
  751.               DrawPieces (PieceToNum(color[t+1], board[t+1]), t+1);
  752.               DrawPieces (PieceToNum(color[t-1], board[t-1]), t-1);
  753.           } else {
  754.               DrawPieces (PieceToNum(color[t+1], board[t+1]), t+1);
  755.               DrawPieces (PieceToNum(color[t-2], board[t-2]), t-2);
  756.           }    
  757.     }
  758.   else
  759.     {
  760.       board[f] = board[t];
  761.       color[f] = color[t];
  762.       board[t] = GameList[GameCnt].piece;
  763.       color[t] = GameList[GameCnt].color;
  764.       DrawPieces(PieceToNum(color[t], board[t]), t);
  765.       DrawPieces(PieceToNum(color[f], board[f]), f);
  766.     }
  767.   if (TCflag[color[f]])
  768.     ++TimeControl.moves[color[f]];
  769.   GameCnt--;
  770.   drawn = mate = false;
  771.   Sdepth = 0;
  772.   Mvboard[f]--;
  773.   for (i=0; i<64; i++) {
  774.       saveColor[i] = color[i];
  775.       saveBoard[i] = board[i];
  776.   }
  777.   InitializeStats ();
  778. }
  779.  
  780. void
  781. ShowCurrentMove (pnt, f, t)
  782.      short int pnt;
  783.      short int f;
  784.      short int t;
  785. {
  786. }
  787.  
  788.  
  789. void
  790. GiveHint ()
  791. {
  792.   char s[40];
  793.   int f, t;
  794.   
  795.   if (!hint) return;
  796.   
  797.   f = hint >> 8;
  798.   t = hint & 0xFF;
  799.   
  800.   algbr ((short) f, (short) t, false);
  801.   ShowCMessage (mvstr[0]);
  802.   AnimePieces(0,PieceToNum(saveColor[f], saveBoard[f]),f, t, 1);
  803.   AnimePieces(PieceToNum(saveColor[t], saveBoard[t]),
  804.                 PieceToNum(saveColor[f], saveBoard[f]),
  805.                     t, f, 1);
  806. }
  807.  
  808.  
  809. void
  810. InputCommand ()
  811. /*
  812.   Process the users command. If easy mode is OFF (the computer is
  813.   thinking on opponents time) and the program is out of book, then make
  814.   the 'hint' move on the board and call SelectMove() to find a response.
  815.   The user terminates the search by entering ^C (quit siqnal) before
  816.   entering a command. If the opponent does not make the hint move, then
  817.   set Sdepth to zero.
  818.   */
  819. {
  820.   short ok, i, tmp;
  821.   long cnt, rate, t1, t2;
  822.   unsigned short mv;
  823.   char s[80];
  824.  
  825.   ok = quit = false;
  826.  
  827.   player = opponent = towho;
  828.   computer = !towho;
  829.   
  830.   ft = 0;
  831.   if (hint > 0 && !easy && Book == NULL)
  832.     {
  833.       preview = 1; idoit = 0;
  834.       time0 = Ticks;
  835.       algbr (hint >> 8, hint & 0xFF, false);
  836.       strcpy (s, mvstr[0]);
  837.       tmp = epsquare;
  838.       if (VerifyMove (s, 1, &mv))
  839.       {
  840.             SelectMove (computer, 2);
  841.             VerifyMove (mvstr[0], 2, &mv);
  842.             if (Sdepth > 0)
  843.                 Sdepth--;
  844.       }
  845.       ft = (Ticks - time0)/60;
  846.       epsquare = tmp;
  847.       preview = 0;
  848.     }
  849.  
  850.   ok = idoit;
  851.   while (!(ok || quit))
  852.   {
  853.         ElapsedTime(0);
  854.       ok = mainLoop();
  855.   }
  856.   ElapsedTime(1);
  857.   ShowCMessage("");
  858. }
  859.  
  860. static void mouseToXY(Point pt, int *OuX, int *OuY)
  861. {
  862.     *OuX = (pt.h/(width-1))+1;
  863.     *OuX = scrntoxy(*OuX);
  864.     *OuY= 8 - (pt.v/(height-1));
  865.     *OuY = scrntoxy(*OuY);
  866. }
  867.  
  868.  
  869. static void followMouse(int *x1, int *y1, Point *Dum)
  870. {
  871.     do {
  872.         GetMouse(Dum);
  873.         PicInRect(&chessRectOff, myDragStuff, Dum);
  874.         mouseToXY(*Dum,x1,y1);
  875.         if ((MouseX!= *x1) || (MouseY != *y1))
  876.         {
  877.             MouseX = *x1; MouseY = *y1;
  878.             UpdateCase(0L,4);
  879.         }
  880.         else
  881.         {
  882.             MouseX = *x1; MouseY = *y1;
  883.         }
  884.         DragItTo(myDragStuff,*Dum,1, FALSE);
  885.          ElapsedTime (0);
  886.     } while (StillDown());
  887. }
  888.  
  889. static void playTheMove(int sq, int x1, int y1, Point Dum)
  890. {
  891.     Point theEnd;
  892.     Rect r;
  893.     
  894.     theEnd = CenterRect(Rectangle(scrntoxy(x1),scrntoxy(9-y1), &r));
  895.     DrawPieces(no_piece, sq);
  896.     DragFromTo(myDragStuff, Dum, theEnd);
  897.     DisposeDraggable(myDragStuff);
  898. }
  899.  
  900.  
  901.  
  902. int MouseInContent(Point MouseLoc, int *eatit)            
  903. {
  904.     int x,y,x1,y1,i,j,ok;
  905.     
  906.     ok = 0;
  907.     if (FrontWindow()==WindList) {
  908.         SetPort(WindList);
  909.         GlobalToLocal(&MouseLoc);
  910.         if (PtInRect(MouseLoc, &theBar)) LClick(MouseLoc, 0, List);
  911.         LocalToGlobal(&MouseLoc);
  912.     } else
  913.     if ((FrontWindow()==WindBoard) && (((opponent == towho) && (!bothsides))
  914.                                     || force) )
  915.     {
  916.         SetPort(WindBoard);
  917.         GlobalToLocal(&MouseLoc);
  918.         mouseToXY(MouseLoc,&x,&y);
  919.         if (y>=1 && y<=8)
  920.          {
  921.              Rect r;
  922.              int Num;
  923.              
  924.              int sq = (y-1)*8+x-1;
  925.              int sq1;
  926.              
  927.              MouseX=x;MouseY=y; UpdateCase(0L,4);
  928.             SetRect(&r,0,0,8*(width-1),8*(height-1));
  929.             if ((saveBoard[sq]!=no_piece)&&(saveColor[sq]==towho))
  930.             {
  931.                 Point Dum;
  932.                 PicHandle h1, h2;
  933.                 char s[6];
  934.                 unsigned int mv;
  935.                 
  936.                 if (preview) {
  937.                     *eatit = false;
  938.                     return 1;
  939.                 }
  940.  
  941.                  Num=PieceToNum(saveColor[sq],saveBoard[sq]);
  942.                 DrawPieces(no_piece ,sq);
  943.                 
  944.                 Dum=MouseLoc;
  945.                 h1=GetPicture(Num);
  946.                 HNoPurge((Handle)(h1));
  947.                 h2=GetPicture(Num-1+Num%4);
  948.                 HNoPurge((Handle)(h1));
  949.         
  950.                 NewDraggable(h1,h2,0L,0L, &myDragStuff);
  951.         
  952.                 HPurge((Handle)(h1));
  953.                 HPurge((Handle)(h2));
  954.         
  955.                  ShadowStuff.visible = 1;
  956.                  ShadowStuff.dx = 4;
  957.                  ShadowStuff.dy = 4;
  958.         
  959.                 followMouse(&x1, &y1, &Dum);
  960.  
  961.                 sq1 = (y1-1)*8+x1-1;
  962.                 if ((saveBoard[sq]==king) && (x1-x == 2)) strcpy(s,"o-o");
  963.                 else 
  964.                 if ((saveBoard[sq]==king) && (x-x1 == 3)) strcpy(s,"o-o-o");
  965.                 else {
  966.                     s[0] = x+'a'-1;
  967.                     s[1] = y+'0';
  968.                     s[2] = x1+'a'-1;
  969.                     s[3] = y1+'0';
  970.                     if (saveBoard[sq] == pawn && (y1 == 8 || y1 == 1)) {
  971.                             s[4] = choosePromo();
  972.                             s[5] = 0;
  973.                     } else  s[4] = 0;
  974.                 }
  975.                 
  976.                 if (ok = VerifyMove(s, 1, &mv)) {
  977.                       if (mv != hint)
  978.                     {
  979.                       Sdepth = 0;
  980.                       ft = 0;
  981.                     }
  982.                     VerifyMove (s, 2, &mv);
  983.                     playTheMove(sq, x1, y1, Dum);
  984.                     VerifyMove (s, 0, &mv);
  985.                     DrawPieces(PieceToNum(color[sq1], board[sq1]), sq1);
  986.                     AddMove(GameCnt, s);
  987.                 } else /* Not valid... Go back home */
  988.                     {
  989.                         Rect r;
  990.                         Point theEnd;
  991.                         theEnd = CenterRect(Rectangle(scrntoxy(x),scrntoxy(9-y), &r));
  992.                         DragFromTo(myDragStuff,Dum,theEnd);
  993.                         DisposeDraggable(myDragStuff);
  994.                     }
  995.         } else while (StillDown());
  996.         LocalToGlobal(&MouseLoc);
  997.     }
  998. }
  999.     return ok;
  1000. }
  1001.  
  1002. int ProcessMenu_in(long CodeWord)
  1003. {
  1004.     MenuHandle MenuTopic;
  1005.     int Menu_No;
  1006.     int Item_No;
  1007.     Str255 NameHolder;
  1008.     int wind,i,Err;
  1009.     Rect nulrec;
  1010.     Handle ItemHdl;
  1011.     
  1012.     int ok = 0;
  1013.     if (CodeWord)
  1014.         {
  1015.         int change = false;
  1016.         Menu_No=HiWord(CodeWord);
  1017.         Item_No=LoWord(CodeWord);
  1018.  
  1019.         switch (Menu_No) {
  1020.  
  1021.             case AppleMenu:
  1022.                 if (Item_No==1) {
  1023.                     Alert(_ABOUT_ALRT, NULL);
  1024.                 }
  1025.                 else {
  1026.                     GetItem(GetMHandle(AppleMenu),Item_No,NameHolder);
  1027.                     OpenDeskAcc(NameHolder);
  1028.                 }
  1029.                 break;
  1030.             case FileMenu:
  1031.                 switch (Item_No) {
  1032.                 case 1:
  1033.                     if (!AreYouSure(_END_STR)) break;
  1034.                     newgame = 1;
  1035.                     donotplay = 1;
  1036.                     ok = true;
  1037.                     break;
  1038.                 case 2:
  1039.                     if (!AreYouSure(_END_STR)) break;
  1040.                     getgame = 1;
  1041.                     donotplay = 1;
  1042.                     ok = true;
  1043.                     break;
  1044.                 case 3:
  1045.                     SaveGame();
  1046.                     break;
  1047.                 case 5:
  1048.                     ListGame();
  1049.                     break;
  1050.                 case 7:
  1051.                     if (!AreYouSure(_END_STR)) break;
  1052.                     donotplay = 1;
  1053.                     quit = true;
  1054.                     ok = true;
  1055.                     break;
  1056.                 }
  1057.                 break;
  1058.  
  1059.             case EditMenu:
  1060.                 if (!SystemEdit(Item_No-1))
  1061.                     switch (Item_No) {
  1062.                         case 1:
  1063.                             if (GameCnt >= 0) {
  1064.                                 undo = 1;
  1065.                                 donotplay = 1;
  1066.                                 Sdepth = 0;
  1067.                                 ok = 1;
  1068.                             }
  1069.                             break;
  1070.                 }
  1071.                 break;
  1072.             case PlayerMenu:
  1073.                 switch (Item_No) {
  1074.                     case 1:
  1075.                         donotplay = true;
  1076.                         bothsides = false;
  1077.                         computer = black;
  1078.                         opponent = white;
  1079.                         ok = true;
  1080.                         force = false;
  1081.                         Sdepth = 0;
  1082.                         break;
  1083.                     case 2:
  1084.                         donotplay = true;
  1085.                         bothsides = false;
  1086.                         computer = white;
  1087.                         opponent = black;
  1088.                         ok = true;
  1089.                         force = false;
  1090.                         Sdepth = 0;
  1091.                         break;
  1092.                     case 3:
  1093.                         donotplay = true;
  1094.                         bothsides = true;
  1095.                         computer = towho;
  1096.                         opponent = !towho;
  1097.                         Sdepth = 0;
  1098.                         ok = true;
  1099.                         force = false;
  1100.                         break;
  1101.                     case 4:
  1102.                         force = true;
  1103.                         bothsides = false;
  1104.                         donotplay = true;
  1105.                         computer = !towho;
  1106.                         opponent = towho;
  1107.                         Sdepth = 0;
  1108.                         ok = true;
  1109.                         break;
  1110.                 }
  1111.                 if (Item_No>0 && Item_No<5)
  1112.                       for (i=1; i<=4; i++)
  1113.                           CheckItem(GetMHandle(Menu_No), i, i==Item_No);
  1114.                 break;
  1115.             case WhiteMenu:
  1116.             case BlackMenu:
  1117.               switch (Item_No)
  1118.                 {
  1119.                   
  1120.                 case 1:
  1121.                   TCmoves[Menu_No==WhiteMenu?white:black] = 60;
  1122.                   TCminutes[Menu_No==WhiteMenu?white:black] = 5;
  1123.                   change = true;
  1124.                   break;
  1125.                 case 2:
  1126.                   TCmoves[Menu_No==WhiteMenu?white:black] = 60;
  1127.                   TCminutes[Menu_No==WhiteMenu?white:black] = 15;
  1128.                   change = true;
  1129.                   break;
  1130.                 case 3:
  1131.                   TCmoves[Menu_No==WhiteMenu?white:black] = 60;
  1132.                   TCminutes[Menu_No==WhiteMenu?white:black] = 30;
  1133.                   change = true;
  1134.                   break;
  1135.                 case 4:
  1136.                   TCmoves[Menu_No==WhiteMenu?white:black] = 40;
  1137.                   TCminutes[Menu_No==WhiteMenu?white:black] = 30;
  1138.                   change = true;
  1139.                   break;
  1140.                 case 5:
  1141.                   TCmoves[Menu_No==WhiteMenu?white:black] = 40;
  1142.                   TCminutes[Menu_No==WhiteMenu?white:black] = 60;
  1143.                   change = true;
  1144.                   break;
  1145.                 case 6:
  1146.                   TCmoves[Menu_No==WhiteMenu?white:black] = 40;
  1147.                   TCminutes[Menu_No==WhiteMenu?white:black] = 120;
  1148.                   change = true;
  1149.                   break;
  1150.                 case 7:
  1151.                   TCmoves[Menu_No==WhiteMenu?white:black] = 40;
  1152.                   TCminutes[Menu_No==WhiteMenu?white:black] = 240;
  1153.                   change = true;
  1154.                   break;
  1155.                 case 8:
  1156.                   TCmoves[Menu_No==WhiteMenu?white:black] = 1;
  1157.                   TCminutes[Menu_No==WhiteMenu?white:black] = 15;
  1158.                   change = true;
  1159.                   break;
  1160.                 case 9:
  1161.                   TCmoves[Menu_No==WhiteMenu?white:black] = 1;
  1162.                   TCminutes[Menu_No==WhiteMenu?white:black] = 60;
  1163.                   change = true;
  1164.                   break;
  1165.                 case 10:
  1166.                   TCmoves[Menu_No==WhiteMenu?white:black] = 1;
  1167.                   TCminutes[Menu_No==WhiteMenu?white:black] = 600;
  1168.                   change = true;
  1169.                   break;
  1170.                 case 12:
  1171.                   change = chooseTime((int *) (&TCmoves[Menu_No==WhiteMenu?white:black])
  1172.                                   ,(int *) (&TCminutes[Menu_No==WhiteMenu?white:black]));
  1173.                   break;
  1174.                 }
  1175.             
  1176.               if (change) {
  1177.                   for (i=1; i<=12; i++)
  1178.                       CheckItem(GetMHandle(Menu_No), i, i==Item_No);
  1179.                   SetTimeControl (Menu_No==WhiteMenu?white:black);
  1180.               }
  1181.               break;
  1182.             case OptionsMenu:
  1183.                 switch (Item_No) {
  1184.                     case 1:
  1185.                         easy = !easy;
  1186.                         CheckItem(GetMHandle(Menu_No), Item_No, easy);
  1187.                         break;
  1188.                     case 2:
  1189.                         reverse = !reverse;
  1190.                         UpdateDisplay(0, 0, 1, 0, 1, saveColor, saveBoard);
  1191.                         CheckItem(GetMHandle(Menu_No), Item_No, reverse);
  1192.                         break;
  1193.                     case 3:
  1194.                         anim = !anim;
  1195.                         CheckItem(GetMHandle(Menu_No), Item_No, anim);
  1196.                         break;
  1197.                     case 4:
  1198.                         dither = dither?0:6;
  1199.                         CheckItem(GetMHandle(Menu_No), Item_No, dither!=0);
  1200.                         break;
  1201.                     case 5:
  1202.                         post = !post;
  1203.                         CheckItem(GetMHandle(Menu_No), Item_No, post);
  1204.                         break;
  1205.                     case 6:
  1206.                         showvalue = !showvalue;
  1207.                         CheckItem(GetMHandle(Menu_No), Item_No, showvalue);
  1208.                         break;
  1209. #ifdef HASHFILE
  1210.                     case 7:
  1211.                         hashflag = !hashflag;
  1212.                         if (hashflag) hashflag = CheckHashFile();
  1213.                         CheckItem(GetMHandle(Menu_No), Item_No, hashflag);
  1214.                         break;
  1215. #endif
  1216.                     case 8:
  1217.                         break;
  1218.                     case 9:
  1219.                         GiveHint();
  1220.                         break;
  1221.                     case 10:
  1222.                         timeout = true;
  1223.                         ok = true;
  1224.                         break;
  1225.                 }
  1226.         }
  1227.  
  1228.         HiliteMenu(0);
  1229.     }
  1230.     return ok;
  1231. }
  1232.  
  1233. int DealwthMouseDowns(EventRecord *Event, int *eatit)
  1234. {
  1235.     int Location;
  1236.     WindowPtr WindowPointedTo;
  1237.     Point MouseLoc,theEnd;
  1238.     int WindoLoc;
  1239.     long Hw,NS;
  1240.     Rect r,rDum;
  1241.     int x,y,x1,y1,i,j;
  1242.     RgnHandle rg;
  1243.     Point Dum;
  1244.     Str255 C;
  1245.     Boolean Bool;
  1246.     int Item,ItemType,Num;
  1247.     Handle ItemHdl;
  1248.     PicHandle h1,h2;
  1249.  
  1250.     *eatit = true;
  1251.     MouseLoc = Event->where;
  1252.     WindoLoc = FindWindow(MouseLoc,&WindowPointedTo);
  1253.     switch (WindoLoc) {
  1254.         case inMenuBar:
  1255.             return ProcessMenu_in((long)MenuSelect(MouseLoc));
  1256.             break;
  1257.         case inSysWindow:
  1258.             SystemClick(Event,WindowPointedTo);
  1259.             break;
  1260.         case inContent:
  1261.             if (WindowPointedTo != FrontWindow()) 
  1262.                 SelectWindow(WindowPointedTo);
  1263.             else return MouseInContent(MouseLoc, eatit);
  1264.             break;
  1265.         case inGrow:
  1266.             if (WindowPointedTo != FrontWindow())
  1267.                 SelectWindow(WindowPointedTo);
  1268.             else
  1269.                 {
  1270.                 Hw = GrowWindow(WindowPointedTo, MouseLoc, &GrowArea);
  1271.                 SizeWindow(WindowPointedTo,Hw & 0xFFFF, Hw>>16, 1);
  1272.                 r = WindowPointedTo->portRect;
  1273.                 ClipRect(&r);
  1274.                 EraseRect(&r);
  1275.                 InvalRect(&r);
  1276.                 }
  1277.                 break;
  1278.         case inDrag:
  1279.                 DragWindow(WindowPointedTo,MouseLoc,&DragArea);
  1280.                 break;
  1281.  
  1282.         case inGoAway:
  1283.                 if (TrackGoAway(WindowPointedTo,MouseLoc))
  1284.                     HideWindow(WindowPointedTo);
  1285.                 break;
  1286.         case inZoomIn:
  1287.         case inZoomOut:
  1288.                 if  (WindowPointedTo != FrontWindow())
  1289.                     SelectWindow(WindowPointedTo);
  1290.                 else
  1291.                 {
  1292.                 ZoomWindow(WindowPointedTo,WindoLoc,1);
  1293.                 r =WindowPointedTo->portRect;
  1294.                 Hw = r.bottom - r.top;
  1295.                 NS = Hw>>16 + r.right - r.left;
  1296.                 if (NS)
  1297.                 {
  1298.                 SizeWindow(WindowPointedTo,NS & 0xFFFF,NS>>16,1);
  1299.                 r = WindowPointedTo->portRect;
  1300.                 ClipRect(&r);
  1301.                 EraseRect(&r);
  1302.                 InvalRect(&r);
  1303.                 }
  1304.                 }
  1305.                 break;
  1306.     }        
  1307.     return 0;
  1308. }
  1309.  
  1310.  
  1311. void DealWthNull(EventRecord *Event)
  1312. {
  1313.     WindowPtr WindowPointedTo;
  1314.     Point MouseLoc;
  1315.     int WindoLoc;
  1316.     int x,y;
  1317.     Boolean Update;
  1318.  
  1319.     WindoLoc=FindWindow(MouseLoc=Event->where,&WindowPointedTo);
  1320.     
  1321.     if ((WindoLoc==inContent) && (WindowPointedTo==WindBoard))
  1322.     {
  1323.         SetPort(WindBoard);
  1324.         GlobalToLocal(&MouseLoc);
  1325.         mouseToXY(MouseLoc,&x,&y);
  1326.         if (y>0 && y<9 && x>0 && x<9)
  1327.         {
  1328.             Update=(MouseX!=x) || (MouseY!=y);
  1329.             MouseX=x;
  1330.             MouseY=y;
  1331.             if (Update) {
  1332.                 UpdateCase(0L,4);
  1333.             }
  1334.         }
  1335.     }
  1336. }
  1337.  
  1338. int mainLoop()
  1339. {
  1340.     EventRecord evt;
  1341.     int ok, eatit, res, item;
  1342.     DialogPtr dlog;
  1343.     char theChar;
  1344.     
  1345.     res = 0;
  1346.     
  1347.     if (wne)
  1348.         ok = WaitNextEvent(everyEvent, &evt, 0L, NULL);
  1349.     else {
  1350.         SystemTask();
  1351.         ok = GetNextEvent(everyEvent, &evt);
  1352.     }
  1353.     if (!ok) {
  1354.         if (force || (towho == opponent)) DealWthNull(&evt);
  1355.         return 0;
  1356.     }
  1357.  
  1358.     eatit = preview;
  1359.     
  1360.     switch (evt.what) {
  1361.         case mouseDown:
  1362.             res = DealwthMouseDowns(&evt, &eatit);
  1363.             break;
  1364.         case keyDown:
  1365.         case autoKey: 
  1366.             theChar = evt.message & charCodeMask;
  1367.             if ((evt.modifiers & cmdKey) != 0) 
  1368.             res = ProcessMenu_in( MenuKey( theChar ));
  1369.             break;
  1370.         case activateEvt: 
  1371.             break;
  1372.         case updateEvt:
  1373.             break;
  1374.         case 15 : /* Multifinder Event */
  1375.             if ((evt.message & 0xFF000000) != 0xFA000000) {
  1376.                         background = !(evt.message & 1);
  1377.             }
  1378.             break;
  1379.         default:
  1380.             break;
  1381.     }
  1382.  
  1383.     if (IsDialogEvent(&evt)) {
  1384.         DialogSelect(&evt, &dlog, &item);
  1385.     }
  1386.  
  1387.     if (!eatit && preview) {
  1388.         static EvQEl globEvt;
  1389.         /* We re-post the event. */
  1390.         globEvt.qType = evType;
  1391.         globEvt.evtQWhat = evt.what;
  1392.         globEvt.evtQMessage = evt.message;
  1393.         globEvt.evtQWhen = evt.when;
  1394.         globEvt.evtQWhere.h = evt.where.h;
  1395.         globEvt.evtQWhere.v = evt.where.v;
  1396.         globEvt.evtQModifiers = evt.modifiers;
  1397.         Enqueue((QElemPtr)&globEvt, (QHdrPtr)GetEvQHdr());
  1398.     }
  1399.     return res;
  1400. }
  1401.  
  1402.  
  1403. loop()
  1404. {
  1405.   int i;
  1406.   
  1407.   SetCursor(*ClockCursor);
  1408.   towho = white;
  1409.   opponent = white;
  1410.   computer = black;
  1411.   bothsides = false;
  1412.   force = reverse = post = easy = false;
  1413.   hashflag = false;
  1414.   drawn = 0;
  1415.   NewGame();
  1416.   for (i=0; i<64; i++) {
  1417.       saveBoard[i] = board[i];
  1418.       saveColor[i] = color[i];
  1419.   }
  1420.   theScore = 0;
  1421.   UpdateValue(NULL, 0);
  1422.   *Msg = 0;
  1423.   UpdateMsg(NULL, 3);
  1424.   
  1425.   UpdateDisplay(0,0,1,0,1,color,board);
  1426.   undo = getgame = newgame = preview = 0;
  1427.   while (!(quit))
  1428.     {
  1429.       player = towho;
  1430.       if (force)
  1431.       {
  1432.           opponent = player;
  1433.           computer = otherside[player];
  1434.       }
  1435.       if (bothsides)
  1436.       {
  1437.           computer = player;
  1438.           opponent = otherside[player];
  1439.       }
  1440.      
  1441.       UpdateMenus();
  1442.       
  1443.       if (undo) {
  1444.               Undo();
  1445.               undo = 0;
  1446.               towho = !towho;
  1447.           }
  1448.           if (getgame) {
  1449.             SetCursor(*ClockCursor);
  1450.             Sdepth = 0;
  1451.             GetGame();
  1452.               getgame = 0;
  1453.           }
  1454.           if (newgame) {
  1455.             SetCursor(*ClockCursor);
  1456.               LDelRow(0, 0, List);
  1457.             NewGame();
  1458.             for (i=0; i<64; i++) {
  1459.                   saveColor[i] = color[i];
  1460.                   saveBoard[i] = board[i];
  1461.             }
  1462.             UpdateDisplay(0,0,1,0,1,color,board);
  1463.             towho = white;
  1464.             if (force) {
  1465.                 computer = !towho;
  1466.                 opponent = towho;
  1467.             }
  1468.             if (bothsides) {
  1469.                 computer = towho;
  1470.                 opponent = !towho;
  1471.             }
  1472.             Sdepth = 0;
  1473.               newgame = 0;
  1474.               drawn = 0;
  1475.           }
  1476.           
  1477.       if (mate || drawn)
  1478.           mainLoop();
  1479.       else {
  1480.         if (towho == white)
  1481.                   SetCursor(*ArrowCursor);
  1482.           else    SetCursor(&arrow);
  1483.           
  1484.  
  1485.           for (i=0; i<64; i++) {
  1486.               saveBoard[i] = board[i];
  1487.               saveColor[i] = color[i];
  1488.         }
  1489.  
  1490.           if (((towho == opponent) && !bothsides) || force)
  1491.                   InputCommand();
  1492.           else    SelectMove (towho, 1);
  1493.           
  1494.           if (!donotplay) {
  1495.               towho = !towho;
  1496.         } else donotplay = 0;
  1497.       }
  1498.     }
  1499. }
  1500.  
  1501.